(define
    (lowercase str)
    (list->string (map char-downcase (string->list str)))
)


(define
    (split-list-on-space to_split working-on)
    (cond
        ; Finished
        ((null? to_split)
            (if (null? working-on)
                '()
                (cons (list->string working-on) '())
            )
        )
        ; Character
        ((not (char-whitespace? (car to_split)))
            (split-list-on-space
                (cdr to_split)
                (append working-on (list (car to_split)))
            )
        )
        ; First whitespace delineating end of word
        ((and (char-whitespace? (car to_split)) (not (null? working-on)))
            (cons
                (list->string working-on)
                (split-list-on-space (cdr to_split) '())
            )
        )
        ; Extraneous whitespace
        (else
            (split-list-on-space (cdr to_split) working-on)
        )
    )
)

(define
    (split-on-space str-to-split)
    (split-list-on-space (string->list str-to-split) '())
)

(define
    (make-dict-helper dict-port word-so-far)
    (let
        (
            (letter (read-char dict-port))
        )
        (cond
            ((eof-object? letter) '())
            ((not (char-whitespace? letter))
                (make-dict-helper
                    dict-port
                    (append word-so-far (list (char-downcase letter))))
            )
            (else
                (cons
                    (list->string word-so-far)
                    (make-dict-helper dict-port '())
                )
            )
        )
    )
)


; XXX change to better data structure like trie
(define
    (make-dict dict-port)
    (make-dict-helper dict-port '())
)

(define
    (lookup-word word dict-data)
    (if (not (member (lowercase word) dict-data))
        word
        #f
    )
)

(define
    (check-words words-to-check dict-data)
    (if (null? words-to-check)
        '()
        (let
            (
                (word (car words-to-check))
                (rest (check-words (cdr words-to-check) dict-data))
            )
            (if (not (lookup-word word dict-data))
                rest
                (cons word rest)
            )
        )
    )
)


; Main --------------------------------
(define
    (main dict-port)
    (let*
        (
            (words-to-check (split-on-space (list-ref (command-line-arguments) 1)))
            (dict-data (make-dict dict-port))
            (bad-words (check-words words-to-check dict-data))
        )
        (for-each
            (lambda (word) (begin (display word) (newline)))
            bad-words
        )
    )
)

(call-with-input-file (list-ref (command-line-arguments) 0) main)
